﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HslCommunication.Profinet.Inovance;
using HslCommunication;
using HslCommunication.Profinet.Omron;
using HslCommunication.Profinet.AllenBradley;


namespace Delta
{
    public class ModbusTCP_PLC
    {
        private string IP = "192.168.0.11";
        private int Port = 502;
        
        private InovanceTcpNet  PLC = null;// new MelsecMcNet("192.168.1.110", 6000);
        /// <summary>
        /// 连接状态
        /// </summary>
        private bool _isConnected = false;
        /// <summary>
        /// 上次链接状态
        /// </summary>
        private bool _LastOperationIsSuccess = false;

        private object writeLocker = new object();
        private object readLocker = new object();
        public ModbusTCP_PLC (string ip, int port = 502)
        {
            SetPLC(ip, port);
            Connect();


            
        }

        public bool IsConnected
        {
            get
            {
                return _isConnected;
            }
        }

        /// <summary>
        /// 设置通信地址
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public void SetPLC(string ip, int port=502)
        {
            this.IP = ip;
            this.Port = port;
        }
        /// <summary>
        /// 是否连接中
        /// </summary>
        bool isInConnect=false;

        /// <summary>
        /// 通信连接
        /// </summary>
        public void Connect()
        {
            try
            {
                if(!isInConnect)
                {
                    isInConnect = true;
                    _isConnected = false;
                    //有时会连接不上，需要多次连接
                    for (int i = 0; i < 4; i++)
                    {
                        
                        PLC = new InovanceTcpNet(InovanceSeries.H5U, IP, Port);
                        PLC.DataFormat = HslCommunication.Core.DataFormat.CDAB;
                        OperateResult connect = PLC.ConnectServer();
                        if (!connect.IsSuccess)
                        {
                            _isConnected = false;
                            _LastOperationIsSuccess = false;
                        }
                        else
                        {
                            _isConnected = true;
                            _LastOperationIsSuccess = true;
                            break;
                        }
                        System.Threading.Thread.Sleep(100);
                    }

                    isInConnect = false;
                }
                

            }
            catch (Exception ex)
            {
                _isConnected = false;
                isInConnect = false;
            }


        }

        /// <summary>
        /// 断开连接
        /// </summary>
        public void Disconnect()
        {
            try
            {
                if (PLC != null)
                {
                    PLC.ConnectClose();
                    _isConnected = false;
                    _LastOperationIsSuccess = true;
                }
            }
            catch (Exception ex)
            {
                _LastOperationIsSuccess = false;
            }

        }

        public void Write(string address, short value)
        {
            try
            {
                lock(writeLocker)
                {
                    PLC.Write(address, value); 
                }
            }
            catch (Exception ex)
            {
                Connect();
                _LastOperationIsSuccess = false;
            }
        }
        public void WriteBool(string address, bool value)
        {
            try
            {
                lock (writeLocker)
                {
                    PLC.Write(address, value);
                }
            }
            catch (Exception ex)
            {
                Connect();
                _LastOperationIsSuccess = false;
            }
        }
        public void WriteInt32(string address, int value)
        {
            try
            {
                lock (writeLocker)
                {
                    PLC.Write(address, value);
                }
            }
            catch (Exception ex)
            {
                Connect();
                _LastOperationIsSuccess = false;
            }
        }

        public void WriteInt16(string address, short value)
        {
            try
            {
                lock (writeLocker)
                {
                    PLC.Write(address, value);
                }
            }
            catch (Exception ex)
            {
                Connect();
                _LastOperationIsSuccess = false;
            }
        }



        public int ReadInt32(string address)
        {
            int rt = -1;
            try
            {
             
                lock (readLocker )
                {
                    rt= PLC.ReadInt32(address).Content;
                }
            }
            catch (Exception ex)
            {
                rt = -1;
                Connect();
                _LastOperationIsSuccess = false;
            }
            return rt;
        }
        public short  ReadInt16(string address)
        {
            short rt = -1;
            try
            {

                lock (readLocker)
                {
                    rt = PLC.ReadInt16(address).Content;
                }
            }
            catch (Exception ex)
            {
                rt = -1;
                Connect();
                _LastOperationIsSuccess = false;
            }
            return rt;
        }
        public bool ReadBool(string address)
        {
            bool rt = false ;
            try
            {

                lock (readLocker)
                {
                    rt = PLC.ReadBool(address).Content;
                }
            }
            catch (Exception ex)
            {
                rt = false ;
                Connect();
                System.Windows.Forms.MessageBox.Show(ex.ToString());
                  _LastOperationIsSuccess = false;
            }
            return rt;
        }
    }
}
